package com.itheima.app.manager;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.itheima.app.interceptor.UserHolder;
import com.itheima.app.log.LogWith;
import com.itheima.app.mq.VideoScoreMQSend;
import com.itheima.domain.db.Log;
import com.itheima.domain.db.UserInfo;
import com.itheima.domain.mongo.Comment;
import com.itheima.domain.mongo.Video;
import com.itheima.domain.mongo.Visitor;
import com.itheima.service.db.UserInfoService;
import com.itheima.service.mongo.CommentService;
import com.itheima.service.mongo.VideoService;
import com.itheima.service.mongo.VisitorService;
import com.itheima.util.ConstantUtil;
import com.itheima.vo.CommentVo;
import com.itheima.vo.PageBeanVo;
import com.itheima.vo.VideoVo;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


@Component
@SuppressWarnings("all")
public class VideoManager {
    @DubboReference
    private VideoService videoService;
    @DubboReference
    private UserInfoService userInfoService;
    @Autowired
    private FdfsWebServer webServer;
    @Autowired
    private FastFileStorageClient client;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @DubboReference
    private CommentService commentService;
    @DubboReference
    private VisitorService visitorService;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;
    @Autowired
    private VideoScoreMQSend videoScoreMQSend;

    @Cacheable(value = "tanhua", key = "'video_'+#userId+'_'+#pageNum+'_'+#pageSize")//存入缓存
    //查询小视频
    public PageBeanVo findSmallVideos(Long userId, Integer pageNum, Integer pageSize) {
        //根据rpc查询推荐视频分页
        PageBeanVo pageBeanVo = videoService.findVideoByPage(userId, pageNum, pageSize);
        //创建vo集合
        List<VideoVo> videoVos = new ArrayList<>();
        //取出推荐视频集合 判断非空并遍历
        List<Video> items = (List<Video>) pageBeanVo.getItems();
        if (CollectionUtil.isNotEmpty(items)) {
            for (Video item : items) {
                //创建vo类
                VideoVo videoVo = new VideoVo();
                //根据视频发布人查询出发布人详细信息
                UserInfo userInfo = userInfoService.findById(item.getUserId());
                //封装vo类
                videoVo.setUserInfo(userInfo);
                videoVo.setVideo(item);
                //如果在redis里存在关注标记 修改已经关注状态
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.FOCUS_USER, userId, item.getUserId()))) {
                    videoVo.setHasFocus(1);
                }
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.VIDEO_LIKE, userId, item.getUserId()))) {
                    videoVo.setHasLiked(1);
                }
                //把vo类添加到vo集合
                videoVos.add(videoVo);

            }
        }//把vo集合赋值给分页类
        pageBeanVo.setItems(videoVos);
        //返回
        return pageBeanVo;
    }

    @CacheEvict(value = "tanhua", key = "'video_'+#userId+'_*'")//每次发布视频 清除redis缓存
    //发布视频
    @LogWith(type = "0301")
    public void addSmallVideos(Long userId, MultipartFile videoFile, MultipartFile videoThumbnail) throws IOException {
        //调用FastDFS上传封面
        StorePath picPath = client.uploadFile(videoThumbnail.getInputStream(), videoThumbnail.getSize(),
                FileUtil.extName(videoThumbnail.getOriginalFilename()), null);
        //拼接上传封面后的访问url
        String picUrl = webServer.getWebServerUrl() + picPath.getFullPath();
        //调用FastDFS上传文件
        StorePath videoPath = client.uploadFile(videoFile.getInputStream(), videoFile.getSize(),
                FileUtil.extName(videoFile.getOriginalFilename()), null);
        //拼接上传文件后的访问url
        String videoUrl = webServer.getWebServerUrl() + videoPath.getFullPath();
        //创建视频类 赋值并保存
        Video video = new Video();
        video.setCreated(System.currentTimeMillis());
        video.setUserId(userId);
        video.setPicUrl(picUrl);
        video.setVideoUrl(videoUrl);
        video.setText("什么是快乐星球");
        videoService.saveVideo(video);
        //记录videoScore记录到MQ
        videoScoreMQSend.sendVideo(userId, video.getId(), VideoScoreMQSend.VIDEO_PUBLISH);
    }

    //视频点赞
    @LogWith(type = "0302")
    public void videoLikes(String videoId, Integer commentType) {
        Long userId = UserHolder.get().getId();
        //创建视频点赞类赋值并保存
        Comment comment = new Comment();
        comment.setUserId(userId);
        comment.setCreated(System.currentTimeMillis());
        comment.setPublishId(new ObjectId(videoId));
        Video video = videoService.findVideoById(new ObjectId(videoId));
        comment.setCommentType(commentType);
        comment.setPublishUserId(video.getUserId());
        commentService.saveComment(comment);
        //在redis存入点赞标记
        stringRedisTemplate.opsForValue().set(StrUtil.format(ConstantUtil.VIDEO_LIKE, userId, video.getUserId()), "1");
        //创建访客对象 赋值并保存
        Visitor visitor = new Visitor();
        visitor.setDate(System.currentTimeMillis());
        visitor.setUserId(video.getUserId());
        visitor.setVisitorUserId(userId);
        visitor.setScore(RandomUtil.randomDouble(60, 99));
        visitor.setFrom("小视频");
        visitorService.addVisitor(visitor);
        //记录videoScore记录到MQ
        videoScoreMQSend.sendVideo(userId, new ObjectId(videoId), VideoScoreMQSend.VIDEO_LIKE);

    }

    //视频取消点赞
    @LogWith(type = "0303")
    public void videoDisLikes(String videoId, Integer commentType) {
        Long userId = UserHolder.get().getId();
        //调用rpc根据视频主键查询视频详情信息
        Video video = videoService.findVideoById(new ObjectId(videoId));
        //调用rpc删除视频点赞
        commentService.removeComment(userId, commentType, videoId);
        //删除redis里的视频点赞标记
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.VIDEO_LIKE, userId, video.getUserId()));
        //记录videoScore记录到MQ
        videoScoreMQSend.sendVideo(userId, new ObjectId(videoId), VideoScoreMQSend.VIDEO_DISLIKE);
    }

    //查询视频评论
    public ResponseEntity findVideoComments(String videoId, Integer pageNum, Integer pageSize, Integer commentType) {
        Long userId = UserHolder.get().getId();
        //根据视频主键、类型和分页条件调用rpc查询视频评论分页
        PageBeanVo pageBeanVo = commentService.findCommentByPage(videoId, pageNum, pageSize, commentType);
        //创建vo集合
        List<CommentVo> commentVos = new ArrayList<>();
        //取出视频评论集合
        List<Comment> items = (List<Comment>) pageBeanVo.getItems();
        //判断视频评论集合非空 遍历
        if (CollectionUtil.isNotEmpty(items)) {
            for (Comment item : items) {
                //根据视频评论人查询出评论人详情
                UserInfo userInfo = userInfoService.findById(item.getUserId());
                //创建vo类 赋值 并保存
                CommentVo commentVo = new CommentVo();
                commentVo.setId(item.getId().toHexString());
                commentVo.setContent(item.getContent());
                commentVo.setNickname(userInfo.getNickname());
                commentVo.setAvatar(userInfo.getAvatar());
                commentVo.setCreateDate(DateUtil.formatDateTime(new Date(item.getCreated())));
                commentVo.setLikeCount(item.getLikeCount());
                //判断redis里是否有评论点赞标记
                if (stringRedisTemplate.hasKey(StrUtil.format(ConstantUtil.VIDEO_CONTENTLIKE, userId, item.getPublishUserId()))) {
                    commentVo.setHasLiked(1);
                }
                commentVos.add(commentVo);
            }
        }//把vo集合赋值给分页类 返回页面
        pageBeanVo.setItems(commentVos);
        return ResponseEntity.ok(pageBeanVo);
    }

    //发布视频评论
    @LogWith(type = "0304")
    public void addVideoComments(String videoId, String content, Integer commentType) {
        Long userId = UserHolder.get().getId();
        //创建视频评论类 赋值并保存
        Comment comment = new Comment();
        comment.setCreated(System.currentTimeMillis());
        comment.setPublishId(new ObjectId(videoId));
        comment.setCommentType(commentType);
        comment.setUserId(userId);
        Video video = videoService.findVideoById(new ObjectId(videoId));
        comment.setPublishUserId(video.getUserId());
        comment.setContent(content);
        commentService.saveComment(comment);
        //创建访客类 赋值并保存
        Visitor visitor = new Visitor();
        visitor.setDate(System.currentTimeMillis());
        visitor.setUserId(video.getUserId());
        visitor.setVisitorUserId(userId);
        visitor.setScore(RandomUtil.randomDouble(60, 99));
        visitor.setFrom("小视频");
        visitorService.addVisitor(visitor);
        //记录videoScore记录到MQ
        videoScoreMQSend.sendVideo(userId, new ObjectId(videoId), VideoScoreMQSend.VIDEO_COMMENT);

    }

    //添加视频评论点赞
    public void addVideoCommentsLike(String contentId, Integer commentType) {
        Long userId = UserHolder.get().getId();
        //根据评论主键调用rpc查询出评论详情
        Comment comment = commentService.findCommentById(new ObjectId(contentId));
        //创建视频评论点赞类 赋值并保存
        Comment addComment = new Comment();
        addComment.setCreated(System.currentTimeMillis());
        addComment.setPublishId(comment.getPublishId());
        addComment.setCommentType(commentType);
        addComment.setUserId(userId);
        addComment.setPublishUserId(comment.getPublishUserId());
        commentService.addVideoCommentsLike(contentId, addComment);
        //在redis里存入点赞标记
        stringRedisTemplate.opsForValue().set(StrUtil.format(ConstantUtil.VIDEO_CONTENTLIKE, userId, comment.getPublishUserId()), "1");
        //记录videoScore记录到MQ
        videoScoreMQSend.sendVideo(userId, comment.getPublishId(), VideoScoreMQSend.VIDEO_COMMENTSLiIKE);
    }

    //取消视频评论点赞
    public void delVideoCommentsLike(String contentId, Integer commentType) {
        Long userId = UserHolder.get().getId();
        //根据评论主键调用rpc查询出评论详情
        Comment comment = commentService.findCommentById(new ObjectId(contentId));
        //调用rpc取消视频评论点赞
        commentService.delVideoCommentsLike(contentId, userId, commentType, comment.getPublishUserId());
        //删除视频点赞标记
        stringRedisTemplate.delete(StrUtil.format(ConstantUtil.VIDEO_CONTENTLIKE, userId, comment.getPublishUserId()));
        //记录videoScore记录到MQ
        videoScoreMQSend.sendVideo(userId, comment.getPublishId(), VideoScoreMQSend.VIDEO_DISCOMMENTSLiIKE);

    }
}
